#include "qlinetools.h"

QLineTools::QLineTools(QString ip, uint16_t prot)
{
    this->setIp(ip);
    this->setProt(prot);
}

QLineTools::~QLineTools()
{
    this->DisconnectDev();
    this->deleteLater();
}

QString QLineTools::ip() const
{
    return m_ip;
}

void QLineTools::setIp(const QString &ip)
{
    m_ip = ip;
}

uint16_t QLineTools::prot() const
{
    return m_prot;
}

void QLineTools::setProt(const uint16_t& prot)
{
    if(prot < 65001)
    {
        m_prot = prot;
    }
    else
    {
        m_prot = 6101;
    }
}

// 连接设备的方法
void QLineTools::ConnectDev()
{
    // 初始化TCP套接字
    m_scket = new QTcpSocket();
    // 尝试连接到指定的IP和端口
    m_scket->connectToHost(this->m_ip, this->m_prot);

    // 当成功连接到主机时的处理
    connect(m_scket, &QTcpSocket::connected, this, [ = ]()
    {
        // 发送连接成功的信号
        emit Result("连接成功", 2);
        // 设置连接状态为true
        this->isLine = true;
        // 发送连接状态信号
        emit IsLine(isLine);
    });

    // 当接收到数据时的处理
    connect(m_scket, &QTcpSocket::readyRead, this, [ = ]()
    {
        // 读取所有接收到的数据并发送信号
        QString msg = m_scket->readAll();
        emit Result(msg, 0);
    });

    // 当与主机断开连接时的处理
    connect(m_scket, &QTcpSocket::disconnected, this, [ = ]()
    {
        // 发送断开连接的信号
        emit Result("断开连接", 1);
        // 调用断开设备连接的方法
        this->DisconnectDev();
    });
}

// 断开设备连接的方法
void QLineTools::DisconnectDev()
{
    // 检查当前socket对象是否非空
    if(m_scket != nullptr)
    {
        // 进一步检查socket是否处于打开状态
        if(m_scket->isOpen())
        {
            //m_scket->abort();
            // 正常关闭socket连接
            m_scket->close();
            // 设置连接状态为false
            this->isLine = false;
            // 发出信号，通知界面更新连接状态
            emit IsLine(isLine);
        }

        // 释放socket对象指针
        m_scket = nullptr;
    }
}

/**
 * @brief 发送数据到连接的设备
 * 
 * 本函数尝试向当前连接的设备发送数据。如果设备未连接或发送过程中出现错误，
 * 将通过信号发送错误信息和设备连接状态。
 * 
 * @param s 要发送的数据，可以是任意字符串
 */
void QLineTools::SendData(QString s)
{
    // qDebug() << "QToolLine 线程" << QThread::currentThreadId();
    // 锁定互斥量以防止多线程同时访问共享资源
    m_Mutex.lock();

    // 检查设备连接状态
    if(m_scket == nullptr)
    {
        // 如果设备未连接，发送错误信号并通知设备连接状态
        emit Result("设备未连接", 1);
        emit IsLine(isLine);
    }
    else
    {
        // 如果设备已连接且socket打开，尝试发送数据
        if(m_scket->isOpen())
        {
            // 使用toUtf8()或者toLocal8Bit()，不要用toLatin1(),否则不支持中文字符串
            qint64 ret = m_scket->write(s.toUtf8().data());

            // 如果发送失败，断开设备连接
            if(ret < 0)
            {
                this->DisconnectDev();
            }
        }
    }

    // 解锁互斥量
    m_Mutex.unlock();
}
